package com.mingqijia.gassafety.webserver.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.gap.basic.exception.BizException;
import com.gap.cache.redis.RedisCache;
import com.mingqijia.gassafety.authority.api.resp.config.DictionaryItemRespDTO;
import com.mingqijia.gassafety.authority.dal.command.RemoveDictionaryItemCommand;
import com.mingqijia.gassafety.authority.dal.handler.ConfigureTranslator;
import com.mingqijia.gassafety.authority.dal.helper.ConfigureHolder;
import com.mingqijia.gassafety.authority.dal.provider.DictionaryProvider;
import com.mingqijia.gassafety.db.entity.FieldTemplate;
import com.mingqijia.gassafety.db.entity.Organization;
import com.mingqijia.gassafety.db.entity.auth.DictionaryItemEntry;
import com.mingqijia.gassafety.db.entity.vo.SelectRegionSpIdInfoVo;
import com.mingqijia.gassafety.db.mapper.CmJoinInfoMapper;
import com.mingqijia.gassafety.db.mapper.OrganizationMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.TemplateTypeEnum;
import com.mingqijia.gassafety.shared.handler.GlobalAuthenticationException;
import com.mingqijia.gassafety.webserver.request.CreateDictionaryItemRequest;
import com.mingqijia.gassafety.webserver.request.OrganizationRequest;
import com.mingqijia.gassafety.webserver.request.UpdateDictionaryItemRequest;
import com.mingqijia.gassafety.webserver.response.OrganizationResponse;
import com.mingqijia.gassafety.webserver.service.FieldTemplateService;
import com.mingqijia.gassafety.webserver.service.FileExportService;
import com.mingqijia.gassafety.webserver.service.OrganizationService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 组织层级关系 服务实现类
 * </p>
 *
 * @author li.shiying
 * @since 2023-07-24
 */
@Service
@Slf4j
public class OrganizationServiceImpl extends ServiceImpl<OrganizationMapper, Organization> implements OrganizationService {

    @Autowired
    OrganizationMapper organizationMapper;
    @Autowired
    DictionaryProvider dProvider;
    @Autowired
    ConfigureTranslator translator;
    @Autowired
    ConfigureHolder holder;
    @Autowired
    FieldTemplateService templateService;
    @Autowired
    RedisCache redisCache;
    @Autowired
    CmJoinInfoMapper cmJoinInfoMapper;
    
    @Override
    public List<OrganizationResponse> getList(String spId) {
        LambdaQueryWrapper<Organization> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Organization::getParentId,spId).eq(Organization::getIsDeleted,0);
        List<Organization> list = this.list(queryWrapper);
        if (!CollectionUtil.isEmpty(list)){
            List<OrganizationResponse> collect = list.stream().map(item -> {
                OrganizationResponse response = new OrganizationResponse();
                BeanUtils.copyProperties(item, response);
                return response;
            }).collect(Collectors.toList());
            OrganizationResponse response = new OrganizationResponse();
            response.setSpId(list.get(0).getParentId());
            response.setSpName(list.get(0).getParentName());
            collect.add(response);
            return collect;
        }
        return null;
    }

    @Override
    @Transactional
    public String add(CreateDictionaryItemRequest req) {
        LambdaQueryWrapper<DictionaryItemEntry> queryClause = new LambdaQueryWrapper<>();
        queryClause.eq(DictionaryItemEntry::getDictCode,Constants.ORG_SUMMARY_CODE).eq(DictionaryItemEntry::getIsDeleted,false)
                .eq(DictionaryItemEntry::getValue,req.getValue());
        List<DictionaryItemEntry> dictList = dProvider.list(queryClause);
        log.info("dictList:"+dictList);
        if (!CollectionUtil.isEmpty(dictList)) {
            throw new BizException("类型编码"+req.getValue()+"已存在!");
        }

        String id = dProvider.create(translator.toCommand(req));
        if (!StringUtils.isEmpty(id)) {
            for (OrganizationRequest organizationRequest1 : req.getOrganizationList()) {
                int count = 0;
                for (OrganizationRequest organizationRequest2 : req.getOrganizationList()) {
                    if (organizationRequest1.getSpId().equals(organizationRequest2.getSpId())) {
                        count = count + 1;
                    }
                }
                if (count > 1) {
                    throw new BizException("子组织spId重复!");
                }
            }

            //上级组织的模板类型
            FieldTemplate parentTemplate = templateService.getTemplate(req.getValue());
            for (OrganizationRequest organizationRequest : req.getOrganizationList()) {
                FieldTemplate template = templateService.getTemplate(organizationRequest.getSpId());
                if (!parentTemplate.getTemplateType().equals(template.getTemplateType())){
                    throw new BizException("子组织["+organizationRequest.getSpName()+"]的模板和上级组织的字段模板不一致!");
                }else if (parentTemplate.getTemplateType() == TemplateTypeEnum.TEMPLATE_TYPE_1.getCode()){
                    if (!parentTemplate.getWorkSystemType().equals(template.getWorkSystemType())){
                        throw new BizException("子组织["+organizationRequest.getSpName()+"]的模板和上级组织的安装模板不一致!");
                    }
                    if (!parentTemplate.getAlarmHandleType().equals(template.getAlarmHandleType())){
                        throw new BizException("子组织["+organizationRequest.getSpName()+"]的模板和上级组织的报警模板不一致!");
                    }
                    if (!parentTemplate.getBrokenHandleType().equals(template.getBrokenHandleType())){
                        throw new BizException("子组织["+organizationRequest.getSpName()+"]的模板和上级组织的故障模板不一致!");
                    }
                    if (!parentTemplate.getSkWorkSystemType().equals(template.getSkWorkSystemType())){
                        throw new BizException("子组织["+organizationRequest.getSpName()+"]的模板和上级组织的安防模板不一致!");
                    }
                }
                Organization organization = new Organization();
                organization.setSpId(organizationRequest.getSpId());
                organization.setParentId(req.getValue());
                organization.setParentName(req.getName());
                organization.setSpName(organizationRequest.getSpName());
                boolean insertRst = this.save(organization);
                log.info("新增子组织结果:{},内容:{}",insertRst,organization);
            }
        }
        return id;
    }

    /**
     * 获取上级组织spid
     * @param spId
     * @return
     */
    @Override
    public List<Organization> getParentIdBySpid(String spId) {
        return  organizationMapper.getParentIdBySpid(spId);
    }

    /**
     * 查询子组织和自己的spId列表
     * 如果有子组织，返回自己和自组织spId列表
     * 如果无子组织，返回自己spId列表
     * @param spId
     * @return
     */
    @Override
    public List<String> getSpIds(String spId) {
        List<String> spIds = new ArrayList<>();
        spIds.add(spId);
        LambdaQueryWrapper<Organization> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Organization::getParentId,spId).eq(Organization::getIsDeleted,0);
        List<Organization> list = this.list(queryWrapper);
        if (!CollectionUtil.isEmpty(list)) {
            for (Organization organization : list) {
                spIds.add(organization.getSpId());
            }
        }
        return spIds;
    }

    @Override
    @Transactional
    public void remove(String itemId) {
        DictionaryItemEntry dictionaryItemEntry = dProvider.getById(itemId);
        List<String> itemIds = Arrays.asList(itemId.split(Constants.STR_COMMA));
        boolean removeRst = dProvider.remove(RemoveDictionaryItemCommand.builder().itemIds(itemIds).build());
        if (removeRst) {
            LambdaUpdateWrapper<Organization> updateWrapper = new LambdaUpdateWrapper();
            updateWrapper.eq(Organization::getParentId,dictionaryItemEntry.getValue());
            Organization organization = new Organization();
            organization.setIsDeleted(true);
            this.update(organization,updateWrapper);
        }
    }

    @Override
    public void edit(UpdateDictionaryItemRequest req) {
        if (!dProvider.update(translator.toCommand(req))) {
            throw new BizException("更新操作失败");
        }
        DictionaryItemEntry dictionaryItemEntry = dProvider.getById(req.getId());
        LambdaUpdateWrapper<Organization> updateWrapper = new LambdaUpdateWrapper();
        updateWrapper.eq(Organization::getParentId,dictionaryItemEntry.getValue());
        Organization organization = new Organization();
        organization.setIsDeleted(true);
        this.update(organization,updateWrapper);
        //上级组织的模板类型
        FieldTemplate parentTemplate = templateService.getTemplate(req.getValue());

        for (OrganizationRequest organizationRequest : req.getOrganizationList()) {
            FieldTemplate template = templateService.getTemplate(organizationRequest.getSpId());
            if (!parentTemplate.getTemplateType().equals(template.getTemplateType())){
                throw new BizException("子组织["+organizationRequest.getSpName()+"]的模板和上级组织的字段模板不一致!");
            }else if (parentTemplate.getTemplateType() == TemplateTypeEnum.TEMPLATE_TYPE_1.getCode()){
                if (!parentTemplate.getWorkSystemType().equals(template.getWorkSystemType())){
                    throw new BizException("子组织["+organizationRequest.getSpName()+"]的模板和上级组织的安装模板不一致!");
                }
                if (!parentTemplate.getAlarmHandleType().equals(template.getAlarmHandleType())){
                    throw new BizException("子组织["+organizationRequest.getSpName()+"]的模板和上级组织的报警模板不一致!");
                }
                if (!parentTemplate.getBrokenHandleType().equals(template.getBrokenHandleType())){
                    throw new BizException("子组织["+organizationRequest.getSpName()+"]的模板和上级组织的故障模板不一致!");
                }
                if (!parentTemplate.getSkWorkSystemType().equals(template.getSkWorkSystemType())){
                    throw new BizException("子组织["+organizationRequest.getSpName()+"]的模板和上级组织的安防模板不一致!");
                }
            }
            Organization organize = new Organization();
            organize.setSpId(organizationRequest.getSpId());
            organize.setParentId(req.getValue());
            organize.setParentName(req.getName());
            organize.setSpName(organizationRequest.getSpName());
            boolean insertRst = this.save(organize);
            log.info("新增子组织结果:{},内容:{}",insertRst,organize);
        }
    }

    @Override
    public List<Organization> getChildList(String parentId) {
        LambdaQueryWrapper<Organization> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(Organization::getParentId,parentId).eq(Organization::getIsDeleted,0);
        return this.list(queryWrapper);
    }

    @Override
    public Map<String,String> selectRegionSpIdInfo(){
        Map<String,String> regionSpMap = redisCache.getCacheMap(Constants.GASSAFETY_REGION_SP_INFO);
        if( null!=regionSpMap && !regionSpMap.isEmpty()){
            return regionSpMap;
        }else{
            regionSpMap = new HashMap<>();
            List<SelectRegionSpIdInfoVo> regionSpIdInfoVos = cmJoinInfoMapper.selectRegionSpIdInfo();
            for (SelectRegionSpIdInfoVo selectRegionSpIdInfoVo: regionSpIdInfoVos) {
                String allSpIds = "";
                String[] spIdArr =  selectRegionSpIdInfoVo.getSpIds().split(",");
                Set<String> allSpIdsSet = new HashSet<>(Arrays.asList(spIdArr));
                if( StringUtils.isNotEmpty(selectRegionSpIdInfoVo.getPIds()) ){
                    String[] pIdArr = selectRegionSpIdInfoVo.getPIds().split(",");
                    allSpIdsSet.addAll(Arrays.asList(pIdArr));
                }
                String[] uniqPidArr = new String[allSpIdsSet.size()];
                allSpIdsSet.toArray(uniqPidArr);
                allSpIds = StringUtils.join(uniqPidArr,",");
                regionSpMap.put(selectRegionSpIdInfoVo.getRegionId().toString(),
                        allSpIds);
            }
            log.info("regionSpMap:{}", JSON.toJSONString(regionSpMap));
            redisCache.setCacheMap(Constants.GASSAFETY_REGION_SP_INFO,regionSpMap);
        }
        return regionSpMap;
    }
}